'use strict';
// 状态定义
const STATE = {
  PENDING: 1,
  FULFILLED: 2,
  REJECTED: 3
};

const toString = Object.prototype.toString;
const is = {
  array: Array.isArray || function (v) {
    return toString.call(v) === '[object Array]';
  },
  function: function (v) {
    return toString.call(v) === '[object Function]' || typeof v === 'function';
  },
  state: function (v) {
    for (let key in STATE) {
      if (STATE[key] === v) {
        return true;
      }
    }
    return false;
  },
  thenable: function (v) {
    return v instanceof Promise;
  }
};

function Promise (resolver) {
  if (!is.function(resolver)) {
    throw new TypeError('Promise resolver ' + fun + ' is not a function');
  }

  if (!(this instanceof Promise)) { // 自动使用new
    return new Promise(resolver);
  }
  var self = this;

  // 内部属性
  this._ = {
    value: null,
    reason: null,
    state: STATE.PENDING, // 默认状态
    resolves: [],
    rejects: [],
    transition: function transition (state, value) {
      if (this._.state === state ||
        this._.state !== STATE.PENDING ||
        !is.state(state)) {
        return;
      }

      this._.state = state;
      if (this._.state === STATE.REJECTED) {
        this._.reason = value;
      } else {
        this._.value = value;
      }
      this._.process();
    },
    process: function () {

    },
    resolve: function (v) {
      var value = (is.function(v) && v(self._.value)) || self._.value;
      self._.transition(STATE.FULFILLED, value);
    },
    reject: function (v) {
      var reason = (is.function(v) && v(self._.reason)) || self._.reason;
      self._.transition(STATE.REJECTED, reason);
    }
  };

  function transition (state, value) {
    if (this._.state === state ||
      this._.state !== STATE.PENDING ||
      !is.state(state)) {
      return;
    }

    this._.value = value;
    this._.state = state;
    this._.process();
  }

  resolver(self._.resolve, self._.reject);
}

// 原型函数
Promise.prototype.then = function (fulfill, reject) {
  if (this._.state === STATE.PENDING) {
    is.function(fulfill) && this._.queue.push(fulfill);
  } else if (this._.state === STATE.FULFILLED) {
    is.function(fulfill) && fulfill(this._.value);
  } else if (this._.state === STATE.REJECTED) {
    is.function(reject) && reject(this._.reason);
  }
  return this;
};
Promise.prototype.catch = function (reject) {
  this.then(null, reject);// not strict equal, this can't catch the then error
};
Promise.prototype.finnaly = function () {

};

// 静态函数
Promise.reject = function () {

};
Promise.resolve = function () {

};
Promise.race = function () {

};
Promise.all = function () {

};
